// B端经理WebSocket服务 - 单例模式
import { v4 as uuid } from 'uuid';

export interface WebSocketMessage {
  type: 'message' | 'typing' | 'stopTyping' | 'heartbeat' | 'pong' | 'conversation_update' | 'error' | 'connection_closed';
  sender_id?: string;
  recipient_id?: string;
  content?: string;
  timestamp?: string;
  conversation_id?: string;
  message?: string; // for error messages
  uuid?: string; // 连接唯一标识符
}

export interface ChatMessage {
  id: string;
  sender_id: string;
  recipient_id: string;
  message_type: string;
  content: string;
  timestamp: string;
  status: string;
  conversation_id: string;
}

export interface ConversationState {
  _id: string;
  c_user_id: string;
  b_user_id: string;
  conversation_id: string;
  last_message_content: string;
  last_message_time: string;
  c_user_unread_count: number;
  b_user_unread_count: number;
  created_at: string;
  updated_at: string;
}

type MessageListener = (message: WebSocketMessage) => void;
type ConversationUpdateListener = (conversations: ConversationState[]) => void;

class ManagerWebSocketService {
  private ws: WebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectDelay = 3000;
  private reconnectTimeout: NodeJS.Timeout | null = null;
  private heartbeatInterval: NodeJS.Timeout | null = null;
  private messageListeners: MessageListener[] = [];
  private conversationUpdateListeners: ConversationUpdateListener[] = [];
  private isConnecting = false;
  private connectionUuid: string | undefined = undefined;
  private managerId: string = ''; // 动态设置的经理ID
  private managerName: string = ''; // 经理的真实姓名
  
  constructor() {
    // 构造函数保持为空，或进行一些不依赖于 managerId 的初始化
  }

  // 设置/切换经理，这是启动服务的入口
  setManager(managerId: string, managerName?: string) {
    if (this.managerId === managerId && this.isConnected()) {
      console.log(`Manager ${managerId} is already connected.`);
      return; // 如果是同一个经理且已连接，则不执行任何操作
    }
    
    // 如果存在旧连接，先断开
    if (this.ws) {
      this.disconnect();
    }

    this.managerId = managerId;
    this.managerName = managerName || managerId;
    
    // 延迟一小段时间再连接，确保旧连接已关闭
    setTimeout(() => {
      this.connect();
    }, 100);
  }

  // 获取经理ID
  getManagerId(): string {
    return this.managerId;
  }

  // 获取经理姓名
  getManagerName(): string {
    return this.managerName;
  }

  // 发送断开连接消息的公共方法
  private sendDisconnectMessage(reason: string, _isAbnormal: boolean = false) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      try {
        const disconnectMessage: WebSocketMessage = {
          type: 'connection_closed',
          sender_id: this.managerId,
          recipient_id: 'system',
          content: `理财师 ${this.managerName} (${this.managerId}) ${reason}`,
          timestamp: new Date().toISOString(),
          uuid: this.connectionUuid
        };
        this.ws.send(JSON.stringify(disconnectMessage));
      } catch (error) {
        console.error(`Failed to send disconnect message:`, error);
      }
    }
  }

  connect() {
    if (this.isConnecting || (this.ws && this.ws.readyState === WebSocket.CONNECTING)) {
      return;
    }

    if (!this.managerId) {
      console.error('Manager ID is not set');
      return;
    }

    this.isConnecting = true;
    
    try {
      // 生成连接UUID
      this.connectionUuid = uuid();
      
      // 统一使用相对路径，通过nginx代理到后端服务
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      const wsUrl = `${protocol}//${window.location.host}/ws/${this.managerId}?uuid=${encodeURIComponent(this.connectionUuid)}`;
      
      console.log(`Connecting to WebSocket: ${wsUrl}`);
      this.ws = new WebSocket(wsUrl);

      this.ws.onopen = () => {
        this.isConnecting = false;
        this.reconnectAttempts = 0;
        this.startHeartbeat();
        
        console.log(`理财师 ${this.managerName} (${this.managerId}) connected to WebSocket`);
        
        // 连接成功后，获取会话列表       
        this.refreshConversations();
      };

      this.ws.onmessage = (event) => {
        try {
          const message: WebSocketMessage = JSON.parse(event.data);
          
          // 通知所有消息监听器
          this.messageListeners.forEach(listener => listener(message));
          
          // 如果是会话更新消息，刷新会话列表
          if (message.type === 'conversation_update' || message.type === 'message') {
            this.refreshConversations();
          }
        } catch (error) {
          console.error('Error parsing WebSocket message:', error);
        }
      };

      this.ws.onclose = (event) => {
        console.log(`理财师 ${this.managerName} (${this.managerId}) WebSocket disconnected:`, event.code, event.reason);

        this.isConnecting = false;
        this.stopHeartbeat();
        
        // 如果连接异常关闭，尝试发送connection_closed消息
        if (event.code !== 1000) { // 1000是正常关闭
          this.sendDisconnectMessage(`连接异常断开 (code: ${event.code})`, true);
        }
        
        this.handleReconnect();
      };

      this.ws.onerror = (error) => {
        console.error(`理财师 ${this.managerName} (${this.managerId}) WebSocket error:`, error);
        this.isConnecting = false;
      };

    } catch (error) {
      console.error('Error connecting to WebSocket:', error);
      this.isConnecting = false;
      this.handleReconnect();
    }
  }

  private handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;

      // 如果已有定时器，先清除
      if (this.reconnectTimeout) {
        clearTimeout(this.reconnectTimeout);
      }

      // 记录新的重连定时器
      this.reconnectTimeout = setTimeout(() => {
        this.connect();
      }, this.reconnectDelay);
    } else {
      console.error('Max reconnection attempts reached');
    }
  }

  private startHeartbeat() {
    this.heartbeatInterval = setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        this.sendMessage({
          type: 'heartbeat',
          sender_id: this.managerId,
          timestamp: new Date().toISOString()
        });
      }
    }, 30000); // 每30秒发送心跳
  }

  private stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }

  // 发送消息
  sendMessage(message: WebSocketMessage) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    } else {
      console.error('WebSocket is not connected');
    }
  }

  // 发送聊天消息给C端用户
  sendChatMessage(recipientId: string, content: string) {
    this.sendMessage({
      type: 'message',
      sender_id: this.managerId,
      recipient_id: recipientId,
      content: content,
      timestamp: new Date().toISOString()
    });
  }

  // 发送正在输入状态
  sendTyping(recipientId: string) {
    this.sendMessage({
      type: 'typing',
      sender_id: this.managerId,
      recipient_id: recipientId,
      timestamp: new Date().toISOString()
    });
  }

  // 发送停止输入状态
  sendStopTyping(recipientId: string) {
    this.sendMessage({
      type: 'stopTyping',
      sender_id: this.managerId,
      recipient_id: recipientId,
      timestamp: new Date().toISOString()
    });
  }

  // 添加消息监听器
  addMessageListener(listener: MessageListener) {
    this.messageListeners.push(listener);
  }

  // 移除消息监听器
  removeMessageListener(listener: MessageListener) {
    const index = this.messageListeners.indexOf(listener);
    if (index > -1) {
      this.messageListeners.splice(index, 1);
    }
  }

  // 添加会话更新监听器
  addConversationUpdateListener(listener: ConversationUpdateListener) {
    this.conversationUpdateListeners.push(listener);
  }

  // 移除会话更新监听器
  removeConversationUpdateListener(listener: ConversationUpdateListener) {
    const index = this.conversationUpdateListeners.indexOf(listener);
    if (index > -1) {
      this.conversationUpdateListeners.splice(index, 1);
    }
  }

  // 获取会话列表
  async getConversations(): Promise<ConversationState[]> {
    try { 
      const response = await fetch('/service/chat/conversations');
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();   
      return result.success ? result.data : [];
    } catch (error) {
      console.error('💥 Error fetching conversations:', error);
      return [];
    }
  }

  // 获取会话消息历史
  async getConversationMessages(conversationId: string): Promise<ChatMessage[]> {
    try {
      const response = await fetch(`/service/chat/conversations/${conversationId}/messages`);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const result = await response.json();
      return result.success ? result.data : [];
    } catch (error) {
      console.error('Error fetching conversation messages:', error);
      return [];
    }
  }

  // 标记会话为已读
  async markConversationRead(conversationId: string): Promise<boolean> {
    try {
      const response = await fetch(`/service/chat/conversations/${conversationId}/mark_read?user_id=${this.managerId}`, {
        method: 'PUT',
      });
      const result = await response.json();
      return result.success;
    } catch (error) {
      console.error('Error marking conversation as read:', error);
      return false;
    }
  }

  // 刷新会话列表并通知监听器
  private async refreshConversations() {
    const conversations = await this.getConversations();
    this.conversationUpdateListeners.forEach(listener => listener(conversations));
  }

  // 检查连接状态
  isConnected(): boolean {
    return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
  }

  // 获取用户ID
  getUserId(): string {
    return this.managerId;
  }

  // 断开连接
  disconnect() {
    this.stopHeartbeat();
    // 如果存在未触发的重连定时器，清除它
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
      this.reconnectTimeout = null;
    }
    if (this.ws) {
      // 在关闭前发送断开消息
      this.sendDisconnectMessage('主动断开连接');
      this.ws.onclose = null; // 移除onclose处理器，避免触发重连逻辑
      this.ws.close();
      this.ws = null;
    }
    this.isConnecting = false;
    console.log(`Manager ${this.managerName} (${this.managerId}) connection closed.`);
  }

  // 更新：添加一个updateUserId兼容旧代码，但核心是setManager
  updateUserId(managerId: string, managerName?: string) {
    this.setManager(managerId, managerName);
  }
}

// 创建并导出服务的单例
const managerWebSocketService = new ManagerWebSocketService();
export { managerWebSocketService, ManagerWebSocketService }; 